package com.huatuoyihao.authentication;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;

public class RandomCheckCode {
	private int width;// 图片宽度
	private int height;// 图片高度
	private int codeCount;// 验证码字符个数
	private int lineCount;// 验证码干扰线个数
	private String checkCode;// 验证码
	private BufferedImage buffImg;// 验证码图片buffer
	
	//o与0难以区分，舍弃
	private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',  
            'K', 'L', 'M', 'N',  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',  
            'X', 'Y', 'Z',  '1', '2', '3', '4', '5', '6', '7', '8', '9'
	};
	
	public RandomCheckCode(int width, int height) {
		init();
		this.width = width;
		this.height = height;
	}

	public RandomCheckCode(int width, int height, int codeCount) {
		this(width, height);
		this.codeCount = codeCount;
	}

	public RandomCheckCode(int width, int height, int codeCount, int lineCount) {
		this(width, height, codeCount);
		this.lineCount = lineCount;
	}

	private void init() {
		this.width = 160;
		this.height = 40;
		this.codeCount = 5;
		this.lineCount = 150;
		this.checkCode = null;
		this.buffImg = null;
	}
	
	public void generate(){
		int fontWidth=0;//每个字符的宽度，可用来计算字符的X坐标
		int fontHeight = 0;//每个字符的高度
		int codeY=0;//字符的Y坐标
		int red=0,green=0,blue=0;
		
		fontWidth = width/(codeCount);
		fontHeight = height-2;
		codeY = height-4;
		//图像buffer
		buffImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		Graphics2D g = buffImg.createGraphics();
		//生成随机数
		Random random = new Random();
		//将图像填充为白色
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, width, height);
		//创建字体
		Font font = CheckCodeFont.createFont(fontHeight);
		g.setFont(font);
		
		//绘制干扰线
		for(int i=0;i<lineCount;i++){
			int xStart = random.nextInt(width);
			int yStart = random.nextInt(height);
			int xEnd =xStart+ random.nextInt(width/8);
			int yEnd =yStart+ random.nextInt(height/8);
			g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
			g.drawLine(xStart,yStart,xEnd,yEnd);
		}
		//记录随机生成的验证码
		StringBuffer randomCode = new StringBuffer();
		//绘制验证码
		for(int i=0;i<codeCount;i++){
			String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
			// 产生随机的颜色值，让输出的每个字符的颜色值都将不同。  
            red = random.nextInt(255);  
            green = random.nextInt(255);  
            blue = random.nextInt(255);  
            g.setColor(new Color(red, green, blue));  
            g.drawString(strRand, i * fontWidth+5, codeY); 
            randomCode.append(strRand);
		}
		this.checkCode = randomCode.toString();
	}
	
	public void write(String filePath) throws IOException{
		OutputStream os = new FileOutputStream(filePath);
		write(os);
	}
	
	public void write(OutputStream os) throws IOException{
		ImageIO.write(this.buffImg, "png", os);
	}
	
	public String getCheckCode() {
		return checkCode;
	}

	public BufferedImage getBuffImg() {
		return buffImg;
	}
}

class CheckCodeFont{
	private CheckCodeFont(){}
	public static Font createFont(int fontHeight){
		try{
			Font baseFont = Font.createFont(Font.TRUETYPE_FONT,new ByteArrayInputStream(null));
			return baseFont.deriveFont(Font.PLAIN,fontHeight);
		}
		catch(Exception e){
			return new Font("Arial",Font.PLAIN,fontHeight);
		}
	}
}